package com.zxq.frame.rabbitmq;

import com.alibaba.fastjson.JSON;
import com.rabbitmq.client.Channel;
import com.zxq.factory.FastFrame;
import com.zxq.factory.decoder.impl.IntDecoder;
import com.zxq.factory.utils.CrcUtils;
import com.zxq.frame.core.ExchangeDTO;
import com.zxq.frame.inner.PduFrame;
import com.zxq.frame.inner.WebPduData;
import com.zxq.frame.rabbitmq.config.IRabbitSubscribeHelper;
import com.zxq.frame.rabbitmq.config.RabbitPublishHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.xmlbeans.impl.util.HexBin;
import org.springframework.amqp.core.Message;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class TcpModbusSubscribeHelper implements IRabbitSubscribeHelper {



    /**
     * int 转 hex码
     * @param value
     * @return
     */
    private String intToHex(Integer value){
        String hex =  StringUtils.leftPad(Integer.toHexString(value).toUpperCase(), 2, '0');
        return hex;
    }

   //01 03 0000 0002 C40B

    @Override
    public void receiveWebChannel(Message message, Channel channel) throws Exception {
        String exchangeJson =new String(message.getBody());
        log.info("rec web:" + exchangeJson);
        ExchangeDTO exchangeDTO = JSON.parseObject(exchangeJson,ExchangeDTO.class);

        byte[] webPduBuff = exchangeDTO.getData();
        log.info("rec web pdu:" + HexBin.bytesToString(webPduBuff));

        WebPduData webPduData = new WebPduData();
        FastFrame.decoder(webPduData,webPduBuff);

        PduFrame pduFrame = new PduFrame();
        BeanUtils.copyProperties(webPduData,pduFrame);
        byte[] crcBuff = CrcUtils.makefcs(webPduBuff);
        IntDecoder intDecoder = new IntDecoder();
        Integer crcLen = intDecoder.decoder(crcBuff);
        pduFrame.setCrc(crcLen);
        byte[] pduBuff = FastFrame.encoder(pduFrame);
        log.info("rec web pdu frame:" + HexBin.bytesToString(pduBuff));
        exchangeDTO.setData(pduBuff);


        RabbitPublishHelper.getInstance().mqPublishFrameToNetworkChannel(exchangeDTO);

        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }

    @Override
    public void receiveNetwork(Message message, Channel channel) throws Exception {
        String exchangeJson =new String(message.getBody());
        ExchangeDTO exchangeDTO = JSON.parseObject(exchangeJson,ExchangeDTO.class);

        byte[] frame = exchangeDTO.getData();

        if(frame == null || frame.length == 0) {
            log.info("error frame is empty!");
            return;
        }
        log.info("rec tcp hex:" + HexBin.bytesToString(frame));
        PduFrame pduFrame = new PduFrame();
        FastFrame.decoder(pduFrame,frame);

        String cmdHex = "";
        switch (pduFrame.getFunCode()) {
            case 3:
                cmdHex = intToHex(pduFrame.getAddress()) + intToHex(pduFrame.getFunCode()) + intToHex((int) pduFrame.getData()[0]);
                break;
            case 5:
            case 6:
                cmdHex = intToHex(pduFrame.getAddress()) + intToHex(pduFrame.getFunCode())
                        + intToHex((int) pduFrame.getData()[0] * 256 + pduFrame.getData()[1]);
                break;
        }
        log.info("rec tcp-modbus pdu cmdHex:" + cmdHex);



        ExchangeDTO rstDTO = new ExchangeDTO();
        rstDTO.setDevId(exchangeDTO.getDevId());
        rstDTO.setFrameId(exchangeDTO.getFrameId());
        rstDTO.setCmdHex(cmdHex);

        rstDTO.setData(frame);

        RabbitPublishHelper.getInstance().mqPublishFrameToWebChannel(rstDTO);

        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);

    }

    //01 03 0000 0002
    //0806 0905 0006 01 03 0000 0002
    //3836 3935 3036 31 33 3030 3032

}
